package com.car.serve.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.car.commons.core.model.Result;
import com.car.serve.Param.addServeParam;
import com.car.serve.Param.reviseServeParam;
import com.car.serve.client.UserClient;
import com.car.serve.client.dto.AdminDto;
import com.car.serve.dto.ServeDto;
import com.car.serve.dto.ServeInfoDto;
import com.car.serve.entity.*;
import com.car.serve.exception.ServeException;
import com.car.serve.form.PageServeForm;
import com.car.serve.mapper.InfoProjectMapper;
import com.car.serve.mapper.ServeInfoMapper;
import com.car.serve.mapper.ServeProjectMapper;
import com.car.serve.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.car.serve.util.PageDtoUtil;
import com.car.serve.util.Type;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 董旭
 * @since 2024-08-28
 */
@Service
public class ServeInfoServiceImpl extends ServiceImpl<ServeInfoMapper, ServeInfo> implements ServeInfoService {

    @Resource
    private ServeInfoMapper serveInfoMapper;
    @Resource
    private ServeInfoService serveInfoService;
    @Resource
    private ServeModifyLogService serveModifyLogService;
    @Resource
    private CarTypeService carTypeService;
    @Resource
    private ServeTypeService serveTypeService;
    @Resource
    private InfoProjectService infoProjectService;
    @Resource
    private InfoProjectMapper infoProjectMapper;
    @Resource
    private ServeProjectService serveProjectService;

    @Resource
    private ServeProjectMapper serveProjectMapper;
    @Resource
    private UserClient userClient;

    //新增服务
    @Override
    @Transactional
    public void addServe(addServeParam param) throws Exception {
        //根据条件查询当前服务是否存在
        QueryWrapper<ServeInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("serve_name",param.getServeName());
        ServeInfo serveInfo = serveInfoMapper.selectOne(wrapper);
        if (serveInfo!=null){
            throw new Exception("服务名已存在");
        }
        // 判断服务类别是否存在
        ServeType serveType = serveTypeService.getById(param.getServeTypeId());
        if (serveType == null) {
           throw new Exception("服务类型不存在");
        }
        String serveTypeName = serveType.getServeTypeName();
        // 判断车辆类型是否存在
        CarType carType = carTypeService.getById(param.getCarTypeId());
        if (carType==null){
            throw new Exception("车辆类型不存在");
        }
        String carTypeName = carType.getCarTypeName();
        //新增服务
        ServeInfo serveInfo1 = BeanUtil.toBean(param, ServeInfo.class);
        BigDecimal servePrice = new BigDecimal(0);
        List<ServeProject> list = serveProjectMapper.selectList(new QueryWrapper<ServeProject>().in("project_id", param.getServeProjectIds()));
        for (ServeProject serveProject : list) {
            servePrice = servePrice.add(serveProject.getProjectPrice());
        }
        serveInfo1.setServePrice(servePrice);
        serveInfo1.setServeName(param.getServeName());
        serveInfo1.setServeState(0);
        serveInfo1.setServeTypeId(param.getServeTypeId());
        serveInfo1.setCarTypeId(param.getCarTypeId());
        serveInfo1.setServeDateil(param.getServeDateil());
        serveInfo1.setServeTypeName(serveTypeName);
        serveInfo1.setCarTypeName(carTypeName);
        serveInfoMapper.insert(serveInfo1);
        //服务与服务项目关联表   根据传入的项目ID集合
        List<Integer> serveProjectIds = param.getServeProjectIds();
        int i = 1;
        for (Integer serveProjectId : serveProjectIds) {
            InfoProject infoProject = new InfoProject();
            infoProject.setServeId(serveInfo1.getServeId());
            infoProject.setProjectId(serveProjectId);
            infoProject.setSortValue(i);
            infoProjectService.save(infoProject);
            i++;
        }

    }

    //修改服务信息
    @Override
    @Transactional
    public void reviseServe(reviseServeParam param) throws Exception {
        //根据ID查询服务并判断是否存在
        ServeInfo serveInfo = serveInfoMapper.selectById(param.getServeId());
        if (serveInfo==null){
            throw new ServeException(500,"修改失败不存在该服务信息");
        }
        if (serveInfo.getServeState()!=0)throw new ServeException(3000,"服务已被删除或禁用无法修改");
        //修改前的项目集合
        List<InfoProject> projects = infoProjectMapper.selectList(new QueryWrapper<InfoProject>().in("serve_id", param.getServeId()));
        List<Integer> collect = projects.stream().map(InfoProject::getProjectId).collect(Collectors.toList());
        // 对两个 List 进行排序以便比较
        Collections.sort(collect);
        List<Integer> newProjectIds = param.getServeProjectIds();
        Collections.sort(newProjectIds);
        // 比较新旧项目 ID 集合是否相同
        if (collect.equals(newProjectIds)) throw new ServeException(3000, "传入的项目与现有项目相同，无需修改");

        List<String> oldProjectNames = this.getProjectNames(collect);
        // 获取传入的新项目 ID 集合

        List<String> newProjectNames = this.getProjectNames(newProjectIds);

        // 计算新项目的价格
        BigDecimal newServePrice = new BigDecimal(0);
        List<ServeProject> newProjectList = serveProjectMapper.selectList(new QueryWrapper<ServeProject>().in("project_id", param.getServeProjectIds()));
        for (ServeProject project : newProjectList) {
            newServePrice = newServePrice.add(project.getProjectPrice());
        }
        //获取当前系统时间并修改
        String createTime = DateUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss");
        serveInfo.setModifyTime(createTime);
        //添加修改人
        serveInfo.setAdminId(param.getAdminId());
        Result<AdminDto> adminDtoResult = userClient.selectAdminDto(param.getAdminId());
        String adminName = adminDtoResult.getData().getAdminName();
        // 更新服务价格
        serveInfo.setServePrice(newServePrice);
        serveInfoMapper.updateById(serveInfo);
        //添加修改人
        serveInfo.setAdminId(param.getAdminId());
        serveInfo.setAdminName(adminName);
        serveInfoMapper.updateById(serveInfo);
        // 先删除旧的服务项目关联记录
        infoProjectService.remove(new QueryWrapper<InfoProject>().eq("serve_id", param.getServeId()));
        // 添加新的服务项目关联记录
        for (Integer projectId : param.getServeProjectIds()) {
            InfoProject infoProject = new InfoProject();
            infoProject.setServeId(param.getServeId());
            infoProject.setProjectId(projectId);
            infoProjectService.save(infoProject);
        }
        //修改后的项目集合
        List<InfoProject> newInfoProjectList = infoProjectMapper.selectList(new QueryWrapper<InfoProject>().in("serve_id", param.getServeId()));

        //添加修改服务日志信息
        ServeModifyLog serveModifyLog = new ServeModifyLog();
        serveModifyLog.setServeName(serveInfo.getServeName());
        serveModifyLog.setServeInfoId(serveInfo.getServeId());
        serveModifyLog.setAdminName(adminName);
        //修改后的项目集合
        serveModifyLog.setReviseAfter(newProjectNames);
        serveModifyLog.setAdminId(param.getAdminId());
        //修改前的项目集合
        serveModifyLog.setReviseFormer(oldProjectNames);
        serveModifyLog.setModifyTime(createTime);
        serveModifyLog.setInfoLog("修改服务项目成功");
        serveModifyLogService.save(serveModifyLog);

    }

    public List<String> getProjectNames(List<Integer> ids) {
        List<ServeProject> serveProjects = serveProjectService.listByIds(ids);
        List<String> collect1 = serveProjects.stream().map(ServeProject::getProjectName).collect(Collectors.toList());
        return collect1;
    }
    //禁用服务
    @Override
    public void disableServe(Integer serceId) throws Exception {
        //查询有无该服务并判断
        ServeInfo serveInfo = serveInfoMapper.selectById(serceId);
        if (serveInfo==null)throw new ServeException(500,"服务不存在");
        //判断状态是否正常
        if (serveInfo.getServeState()!=0)throw new Exception("服务被删除或已禁用");
        //修改服务状态
        UpdateWrapper<ServeInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("serve_state",1);
        updateWrapper.eq("serve_state",0).eq("serve_name",serveInfo.getServeName());
        serveInfoService.update(null,updateWrapper);

    }

    @Override
    public void enableServe(Integer serveId) throws Exception {
        //查询有无该服务并判断
        ServeInfo serveInfo = serveInfoMapper.selectById(serveId);
        if (serveInfo==null)throw new ServeException(500,"服务不存在");
        //判断状态是否正常
        if (serveInfo.getServeState()!=1)throw new Exception("服务被删除或已启用");
        UpdateWrapper<ServeInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("serve_state",0);
        updateWrapper.eq("serve_state",1).eq("serve_name",serveInfo.getServeName());
        serveInfoService.update(null,updateWrapper);
    }

    @Override
    public Page<ServeInfo> findServePage(PageServeForm form) {
        Page<ServeInfo> page = new Page<>(form.getPageNum() == null ? 1 : form.getPageNum(), form.getPageSize() == null ? 6 : form.getPageSize());
        QueryWrapper<ServeInfo> wrapper = new QueryWrapper<>();
        //判断服务名是否为空
        if (ObjectUtil.isNotEmpty(form.getServeName())) {
            wrapper.like("serve_name", form.getServeName());
        }
        //判断状态是否为空
        if (ObjectUtil.isNotEmpty(form.getServeState())) {
            wrapper.eq("serve_state", form.getServeState());
        }
        // 排除状态为 2 的数据
        wrapper.ne("serve_state", 2);
        Page<ServeInfo> serveInfoPage = serveInfoMapper.selectPage(page, wrapper);
//        Page<ServeInfoDto> serveInfoDtoPage = PageDtoUtil.convertPage(serveInfoPage, ServeInfoDto.class);
        return serveInfoPage;
    }

    @Override
    public void delServe(Integer serveId)throws ServeException {
        ServeInfo serveInfo = serveInfoMapper.selectById(serveId);
        if (serveInfo==null)throw new ServeException(5000,"服务不存在");
        if (serveInfo.getServeState()==2)throw new ServeException(5000,"该服务已被删除");
        //根据条件更新状态为删除
        UpdateWrapper<ServeInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("serve_state", Type.BOOKTYPE_STATE_DELETE);
        updateWrapper.eq("serve_name",serveInfo.getServeName());
        serveInfoMapper.update(null,updateWrapper);
        //查询该服务的服务和项目关联表删除
        QueryWrapper<InfoProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("serve_id", serveId);
        infoProjectMapper.delete(queryWrapper);
    }

    @Override
    public ServeInfoDto findById(Integer serveId) throws Exception {
        //查询服务信息
        ServeInfo byId = serveInfoService.getById(serveId);
        if (byId.getServeState()!=0)throw new ServeException(3000,"状态异常无法查看");
        //查询服务的所有项目
        QueryWrapper<InfoProject> wrapper = new QueryWrapper<>();
        wrapper.eq("serve_id",serveId);
        List<InfoProject> infoProjects = infoProjectService.list(wrapper);
        if (infoProjects.isEmpty()) {
            throw new ServeException(4001, "服务没有关联的项目");
        }
        List<Integer> collect = infoProjects.stream().map(o -> o.getProjectId()).collect(Collectors.toList());
        //根据项目ID去查询项目信息
        QueryWrapper<ServeProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("project_id",collect);
        List<ServeProject> list = serveProjectService.list(queryWrapper);
        ServeInfoDto serveInfoDto1 = BeanUtil.toBean(byId, ServeInfoDto.class);
        serveInfoDto1.setServeProjectList(list);
        serveInfoDto1.setServeTypeName(byId.getServeTypeName());
        serveInfoDto1.setCarTypeName(byId.getCarTypeName());
        return serveInfoDto1;
    }

    @Override
    public void changeServeScore(ServeDto serveDto) {
        ServeInfo serveInfo = serveInfoService.getById(serveDto.getServeId());
        if (serveInfo==null)throw new ServeException(3000,"服务不存在");
        if (serveInfo.getServeState()!=0)throw new ServeException(3000,"状态异常");
        serveInfo.setScore(serveDto.getScore());
        serveInfoMapper.updateById(serveInfo);
    }
}
